package com.lmx.common.util;

import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.SimpleTimeZone;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.querydsl.core.types.dsl.PathBuilder;

import io.katharsis.queryParams.QueryParams;
import io.katharsis.queryParams.params.FilterParams;
import io.katharsis.queryParams.params.TypedParams;

/**
 * Created by qin on 2016/6/15.
 */
public class CommonUtil {
	private static Log logger = LogFactory.getLog(CommonUtil.class);

	/**
	 * 查询参数转换(filter)
	 *
	 * @param requestParams
	 * @return Map<String ,String> key value
	 */
	public static Map<String, String> getKeyMapByFilter(QueryParams requestParams) {
		Iterator<String> it = requestParams.getFilters().getParams().keySet().iterator();
		Map<String, String> keyMap = new HashMap<String, String>();
		// 获取条件
		while (it.hasNext()) {
			String key = it.next();
			TypedParams<FilterParams> filters = requestParams.getFilters();
			Map<String, FilterParams> params = filters.getParams();
			Iterator<String> paramsIt = params.keySet().iterator();
			while (paramsIt.hasNext()) {
				// 条件初始化
				String fpkey = null;
				String value = null;

				String pkey = paramsIt.next();
				FilterParams fp = params.get(pkey);
				Map<String, Set<String>> map = fp.getParams();
				Iterator<String> fpIt = map.keySet().iterator();

				// 兼容 filter[0][field] filter[field]
				if (!"0".equals(pkey)) {
					while (fpIt.hasNext()) {
						fpkey = fpIt.next();
						Set<String> keyValue = map.get(fpkey);
						Iterator<String> vit = keyValue.iterator();
						while (vit.hasNext()) {
							value = vit.next();
							if ("".equals(fpkey)) {
								fpkey = pkey;
							} else {
								pkey = pkey.replace("---" + pkey.substring(pkey.length() - 1), "");// 去除客户端冗余
								fpkey = pkey + "." + fpkey;
							}
							keyMap.put(fpkey, value);
						}
					}

				} else {
					while (fpIt.hasNext()) {
						fpkey = fpIt.next();
						Set<String> keyValue = map.get(fpkey);
						Iterator<String> vit = keyValue.iterator();
						while (vit.hasNext()) {
							value = vit.next();
							keyMap.put(fpkey, value);
						}
					}
				}

			}
		}
		return keyMap;
	}

	/**
	 * 判断字段属性是否为数值型
	 *
	 * @param pathBuilder
	 * @param key
	 * @return flag
	 */
	public static boolean checkFieldIsNumber(PathBuilder<?> pathBuilder, String key) {
		if ("id".equals(key)
				|| (key.split("\\.", -1).length > 1 && "id".equals(key.split("\\.", -1)[key.split(
						"\\.", -1).length - 1]))) {
			return true;
		}
		logger.debug("key:" + key);
		boolean flag = false;
		// 根据反射机制获取字段属性
		Field field = null;
		try {
			if (key.indexOf(".") == -1) {
				field = pathBuilder.getType().getDeclaredField(key);
			} else {
				String[] fieldArray = key.split("\\.", -1);
				Class clazz = pathBuilder.getType();
				for (int i = 0; i < fieldArray.length; i++) {
					field = clazz.getDeclaredField(fieldArray[i]);
					clazz = (Class) field.getGenericType();
				}
			}
		} catch (Exception e) {
			logger.debug("没有找到相应字段！");
		}

		String fieldType = "";
		if (key.indexOf("delStatus") > -1) {
			fieldType = "short";
		} else {
			fieldType = field.getGenericType().toString();
		}

		if (fieldType.equals("int") || fieldType.equals("class java.lang.Integer")
				|| fieldType.equals("double") || fieldType.equals("class java.lang.Double")
				|| fieldType.equals("short") || fieldType.equals("class java.lang.Short")
				|| fieldType.equals("long") || fieldType.equals("class java.lang.Long")) {
			flag = true;
		}
		return flag;
	}

	/**
	 * 检测是否为多对多查询
	 *
	 * @param pathBuilder
	 * @param key
	 * @return
	 */
	public static boolean checkFieldIsSet(PathBuilder<?> pathBuilder, String key) {
		boolean flag = false;
		Field field = null;
		try {
			if (key.indexOf(".") > -1) {
				field = pathBuilder.getType().getDeclaredField(key.split("\\.", -1)[0]);
				String className = field.getGenericType().toString();
				if (className.indexOf("Set") > -1 || className.indexOf("List") > -1) {
					flag = true;
				}
			}
		} catch (Exception e) {
			logger.debug("没有找到相应字段！");
		}
		return flag;
	}

	/**
	 * 判断字符串是否数值
	 *
	 * @param str
	 * @return true:是数值 ；false：不是数值
	 * @author:WD_SUHUAFU
	 */
	private static boolean isNumber(final String str) {
		final Pattern pattern = Pattern.compile("^[0-9]+(.[0-9]*)?$");
		final Matcher match = pattern.matcher(str);
		return match.matches();
	}

	/**
	 * 生成验证码(随机6位数)
	 *
	 * @return
	 */
	public static int getValidationNum() {
		Random random = new Random();
		return random.nextInt(899999) + 100000;
	}

	/**
	 * map转json字符串
	 *
	 * @param map
	 * @return json String
	 */
	public static String mapToJsonString(Map map) {
		ObjectMapper mapper = new ObjectMapper();
		String json = null; // 返回json串
		try {
			json = mapper.writeValueAsString(map);
		} catch (Exception e) {
			logger.debug("json 转换异常!   " + e.toString());
		}
		return json;
	}

	/**
	 * 获取当前时间 yyyyMMddHHmmss
	 *
	 * @return String
	 */
	public static String getCurrTime() {
		Date now = new Date();
		SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		String s = outFormat.format(now);
		return s;
	}

	/**
	 * 获取当前时间 YYYY-MM-DDThh:mm:ssZ
	 *
	 * @return String
	 */
    public static String newIOSTimeStamp() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
        return df.format(new Date());
    }
	
	/**
	 * 获取当前时间
	 *
	 * @return
	 */
	public static String getCurrTimeForString() {
		Date date = new Date();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取昨天时间
	 *
	 * @return
	 */
	public static int getTomorrowCurrTime() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, 1);
		// Date date = cal.getTime();
		// SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		// String dateStr = sim.format(date);
		// return dateStr;
		return (int) (cal.getTimeInMillis() / 1000);
	}

	/**
	 * 获取昨天时间
	 *
	 * @return
	 */
	public static String getYesterdayCurrTimeForString() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -1);
		Date date = cal.getTime();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取前天时间
	 *
	 * @return
	 */
	public static String getBeforeYesterdayCurrTimeForString() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.DATE, -2);
		Date date = cal.getTime();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取昨上一月第一天
	 *
	 * @return
	 */
	public static String getPreMonthFirstDayForString() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, -1);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		Date date = cal.getTime();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取昨上一月最后一天
	 *
	 * @return
	 */
	public static String getPreMonthLastDayForString() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.add(Calendar.DATE, -1);
		Date date = cal.getTime();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取月第一天
	 *
	 * @return
	 */
	public static String getMonthFirstDayForString() {
		Calendar cal = Calendar.getInstance();
		cal.add(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		Date date = cal.getTime();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取月最后一天
	 *
	 * @return
	 */
	public static String getMonthLastDayForString() {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
		Date date = cal.getTime();
		SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = sim.format(date);
		return dateStr;
	}

	/**
	 * 获取当前时间戳
	 *
	 * @return
	 */
	public static int getCurrTimes() {
		return (int) (System.currentTimeMillis() / 1000);
	}

	/**
	 * 获取当天0点时间戳
	 */
	public static int getDayBegin() {
		return CommonUtil.getDayBegin(new Date());
	}

	/**
     * 获取当天23:59:59点时间戳
     */
    public static int getDayEnd() {
        return CommonUtil.getDayEnd(new Date());
    }

    
	/**
	 * 获取当天0点时间戳
	 *
	 * @author ytche
	 * @param date
	 * @return
	 * @date 2017年6月1日 下午3:56:40
	 */
	public static int getDayBegin(Date date) {
		Calendar cal = Calendar.getInstance();
		if (date != null) {
			cal.setTime(date);
		}
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND, 001);
		return (int) (cal.getTimeInMillis() / 1000);
	}

	   /**
     * 获取当天最后一秒时间戳
     *
     * @author lmx
     * @param date
     * @return
     * @date 2017年9月15日 下午3:56:40
     */
    public static int getDayEnd(Date date) {
        Calendar cal = Calendar.getInstance();
        if (date != null) {
            cal.setTime(date);
        }
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 999);
        return (int) (cal.getTimeInMillis() / 1000);
    }
    
	/**
	 * 获取当天0点时间戳
	 *
	 * @author ytche
	 * @param startTime
	 * @return
	 * @date 2017年6月20日 下午4:41:26
	 */
	public static Integer getDayBegin(Integer dateInt) {
		Date date = new Date(dateInt.longValue() * 1000);
		return CommonUtil.getDayBegin(date);
	}

	/**
	 * 复制非空属性
	 *
	 * @param src
	 * @param target
	 */
	public static void copyNonNullProperties(Object src, Object target) {
		BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
	}

	/**
	 * 获取对象空属性集合
	 *
	 * @param source
	 * @return
	 */
	public static String[] getNullPropertyNames(Object source) {
		final BeanWrapper src = new BeanWrapperImpl(source);
		java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
		Set<String> emptyNames = new HashSet<String>();
		for (java.beans.PropertyDescriptor pd : pds) {
			Object srcValue = src.getPropertyValue(pd.getName());
			logger.debug("update:" + pd.getName() + "--" + srcValue);
			if (srcValue == null)
				emptyNames.add(pd.getName());
		}
		String[] result = new String[emptyNames.size()];
		return emptyNames.toArray(result);
	}

	/**
	 * Integer时间格式化
	 *
	 * @return
	 */
	public static String integetTimeForString(Integer time) {
		String dateStr = null;
		if (time != null) {
			Long longTime = new Long(time);
			Date date = new Date(longTime * 1000);
			SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			dateStr = sim.format(date);
		}
		return dateStr;
	}

	/**
	 * 时间秒数转化为小时分钟
	 *
	 * @return
	 */
	public static String timeChange(Integer seconds) {
		String dateStr = "";
		if (seconds != null) {
			int hour = seconds / 3600;
			int minute = (seconds - hour * 3600) / 60;
			int second = (seconds - hour * 3600 - minute * 60);
			dateStr = hour + ":" + minute + ":" + second;
		}
		return dateStr;
	}

	/**
	 * 判断字符串是否为数字
	 */
	public static boolean isNumeric(String str) {
		for (int i = 0; i < str.length(); i++) {
			System.out.println(str.charAt(i));
			if (!Character.isDigit(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 格式化日期转时间戳
	 *
	 * @return
	 * @throws ParseException
	 */
	public static Integer strToIntegerTime(String timeStr) throws ParseException {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Integer time = null;
		if (timeStr != null && !timeStr.isEmpty()) {
			Date date = dateFormat.parse(timeStr);
			Long timeL = date.getTime() / 1000;
			time = new Integer(timeL.intValue());
		}
		return time;
	}

	/***
	 * MD5加码 生成32位md5码
	 */
	public static String stringMD5(String inStr) {
		MessageDigest md5 = null;
		try {
			md5 = MessageDigest.getInstance("MD5");
		} catch (Exception e) {
			logger.debug(e.toString());
			return "";
		}
		char[] charArray = inStr.toCharArray();
		byte[] byteArray = new byte[charArray.length];

		for (int i = 0; i < charArray.length; i++)
			byteArray[i] = (byte) charArray[i];
		byte[] md5Bytes = md5.digest(byteArray);
		StringBuffer hexValue = new StringBuffer();
		for (int i = 0; i < md5Bytes.length; i++) {
			int val = (md5Bytes[i]) & 0xff;
			if (val < 16)
				hexValue.append("0");
			hexValue.append(Integer.toHexString(val));
		}
		return hexValue.toString();

	}

	/**
	 * 获取当天某点时间戳
	 */
	public static int getDayHoure(Integer houres) {
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, houres);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.MILLISECOND, 001);
		return (int) (cal.getTimeInMillis() / 1000);
	}

	/**
	 * 随机字符串
	 */
	public static String createNonceStr() {
		Random random = new Random();
		return CommonUtil.stringMD5(String.valueOf(random.nextInt(10000)));
	}

	/**
	 * MD5加密
	 *
	 * @param origin
	 * @param charsetname
	 * @return
	 */
	public static String MD5Encode(String origin, String charsetname) {
		String resultString = null;
		try {
			resultString = new String(origin);
			MessageDigest md = MessageDigest.getInstance("MD5");
			if (charsetname == null || "".equals(charsetname))
				resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
			else
				resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
		} catch (Exception exception) {
		}
		return resultString;
	}

	private static String byteArrayToHexString(byte b[]) {
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++)
			resultSb.append(byteToHexString(b[i]));

		return resultSb.toString();
	}

	private static String byteToHexString(byte b) {
		int n = b;
		if (n < 0)
			n += 256;
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}

	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
			"a", "b", "c", "d", "e", "f" };

	/**
	 * URLEncoding
	 */
	public static String URLEncoding(String str) {
		try {
			str = java.net.URLEncoder.encode(str, "utf-8");
		} catch (Exception e) {
			logger.debug(e.toString());
		}
		return str;
	}

	/**
	 * 获取订单号
	 */
	public static String getOrderNo() {
		String dateStr = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
		String orderNo = dateStr + CommonUtil.getValidationNum();
		return orderNo;
	}

	/**
	 * * 获取指定日期是星期几 参数为null时表示获取当前日期是星期几
	 *
	 * @param date
	 * @return
	 */
	public static String getWeekOfDate(Date date) {
	    String[] weekOfDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};        
	    Calendar calendar = Calendar.getInstance();      
	    if(date != null){        
	         calendar.setTime(date);      
	    }        
	    int w = calendar.get(Calendar.DAY_OF_WEEK) - 1;      
	    if (w < 0){        
	        w = 0;      
	    }      
	    return weekOfDays[w];   
	}

	public static String getPropertyName(String dataClassName, String entityClassName) {
		String name = null;
		Class<?> clsData = null;
		try {
			clsData = Class.forName(dataClassName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Field[] fieldlist = clsData.getDeclaredFields();
		for (int i = 0; i < fieldlist.length; i++) {
			Field fld = fieldlist[i];
			if (fld.getGenericType().toString().equals("class " + entityClassName)) {
				name = fld.getName();
				break;
			}
		}
		return name;
	}

	// 生成随机数字和字母,
	public static String getStringRandom(int length) {

		String val = "";
		Random random = new Random();

		// 参数length，表示生成几位随机数
		for (int i = 0; i < length; i++) {

			String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
			// 输出字母还是数字
			if ("char".equalsIgnoreCase(charOrNum)) {
				// 输出是大写字母还是小写字母
				int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
				val += (char) (random.nextInt(26) + temp);
			} else if ("num".equalsIgnoreCase(charOrNum)) {
				val += String.valueOf(random.nextInt(10));
			}
		}
		return val;
	}

	/**
	 * 取出一个指定长度大小的随机正整数.
	 *
	 * @param length
	 *            int 设定所取出随机数的长度。length小于11
	 * @return int 返回生成的随机数。
	 */
	public static int buildRandom(int length) {
		int num = 1;
		double random = Math.random();
		if (random < 0.1) {
			random = random + 0.1;
		}
		for (int i = 0; i < length; i++) {
			num = num * 10;
		}
		return (int) ((random * num));
	}

	public static String create_nonce_str() {
		return UUID.randomUUID().toString();
	}

	public static String create_timestamp() {
		return Long.toString(System.currentTimeMillis() / 1000);
	}

	/**
	 * 计算日期是第几周
	 */
	public static int getWeekIndex(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setFirstDayOfWeek(Calendar.MONDAY);
		cal.set(Calendar.YEAR, date.getYear() + 1900);
		cal.set(Calendar.MONTH, date.getMonth() + 1);
		cal.set(Calendar.DATE, date.getDay());
		// 53
		System.out.println(cal.get(Calendar.WEEK_OF_YEAR));
		return cal.get(Calendar.WEEK_OF_YEAR);
	}

	// 获得当前日期与本周日相差的天数
	public static int getMondayPlus(Date gmtCreate) {
		Calendar cd = Calendar.getInstance();
		cd.setTime(gmtCreate);
		// 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
		int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
		if (dayOfWeek == 1) {
			return 0;
		} else {
			return 1 - dayOfWeek;
		}
	}

	// 获得下周星期一的日期
	public static Date getNextMonday(Date gmtCreate, int weekNum) {
		int mondayPlus = getMondayPlus(gmtCreate);
		GregorianCalendar currentDate = new GregorianCalendar();
		currentDate.add(GregorianCalendar.DATE, mondayPlus + weekNum * 7);
		Date monday = currentDate.getTime();
		return monday;
	}

	// 获得下周星期日的日期
	public static Date getNextSaturday(Date gmtCreate, int weekNum) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(gmtCreate);
		// weekNum为推迟的周数，0本周，-1向前推迟一周，2下周，依次类推
		cal.add(Calendar.DATE, weekNum * 7);
		// 想周几，这里就传几Calendar.MONDAY（TUESDAY...）
		cal.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
		Date monday = cal.getTime();
		return monday;
	}

	// 日期是周几
	public static int getWeek(Date date) {
		// int m = date.getMonth();
		// int y = date.getYear()+1900;
		// int d = date.getDay();
		// if (m < 3) {
		// m += 12;
		// --y;
		// }
		// int w = (d + 1 + 2 * m + 3 * (m + 1) / 5 + y + (y >> 2) - y / 100
		// + y / 400) % 7;
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
			w = 0;
		return w;
	}

	// 是第几周
	public static int getWeekIndexFromSun(Date date) {
		Date dateSat = getNextSaturday(date, 0);// 获取date所在周的周六
		// Date dateSat=date ;//获取date所在周的周六
		Integer totaldays = 0;
		Integer year = dateSat.getYear() + 1900;
		Integer month = dateSat.getMonth();
		Integer day = dateSat.getDate();
		Integer[] days = new Integer[12];
		days[0] = 31;
		days[2] = 31;
		days[3] = 30;
		days[4] = 31;
		days[5] = 30;
		days[6] = 31;
		days[7] = 31;
		days[8] = 30;
		days[9] = 31;
		days[10] = 30;
		days[11] = 31;
		if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
			days[1] = 29;
		} else {
			days[1] = 28;
		}
		if (month == 0) {
			totaldays = totaldays + day;
		} else {
			for (int count = 1; count <= month; count++) {
				// System.out.println(totaldays+" "+days[count - 1]);
				totaldays = totaldays + days[count - 1];
			}
			totaldays = totaldays + day;
		}
		// System.out.println(totaldays*1.0 / 7);
		int week = (int) Math.ceil(totaldays * 1.0 / 7);
		return week;
	}

	// 产生区间内随机数
	public static int randomInt(int max, int min) {
		Random random = new Random();
		int s = random.nextInt(max) % (max - min + 1) + min;
		return s;
	}

	/**
	 * 获取某日当天的最后时间
	 *
	 * @author ytche
	 * @param date
	 * @return
	 * @date 2017年5月3日 上午10:25:58
	 */
	public static Long getLastSecondOfDay(Date date) {
		Calendar todayEnd = Calendar.getInstance();
		todayEnd.setTime(date);
		todayEnd.set(Calendar.HOUR, 23);
		todayEnd.set(Calendar.MINUTE, 59);
		todayEnd.set(Calendar.SECOND, 59);
		todayEnd.set(Calendar.MILLISECOND, 999);
		return todayEnd.getTime().getTime();
	}

	// /**
	// * 获取某周第一天的零点时间
	// *
	// * @author ytche
	// * @param date
	// * @return
	// * @date 2017年6月29日 上午10:09:00
	// */
	// public static Integer getWeekBegin(Date date) {
	// return CommonUtil.getBeginTime(Calendar.DAY_OF_WEEK, date);
	// }

	/**
	 * 获取某周第一天的零点时间
	 *
	 * @author ytche
	 * @param date
	 * @param isMondayBegin
	 *            //是否是周一开始
	 * @return
	 * @date 2017年6月29日 上午10:09:00
	 */
	public static Integer getWeekBegin(Date date, Boolean isMondayBegin) {
		if (isMondayBegin) {
			return CommonUtil.getBeginTime(Calendar.DAY_OF_WEEK, date) + 3600 * 24;
		}
		return CommonUtil.getBeginTime(Calendar.DAY_OF_WEEK, date);
	}

	/**
	 * 获取当周第一天的零点时间
	 *
	 * @author ytche
	 * @return
	 * @date 2017年6月29日 上午10:24:57
	 */
	public static Integer getWeekBegin() {
		return CommonUtil.getWeekBegin(new Date(), false);
	}

	/**
	 * 获取当周第一天零点时间
	 *
	 * @author ytche
	 * @param dateStr
	 *            "yyyy-MM-dd"
	 * @return
	 * @date 2017年7月27日 下午5:28:48
	 */
	public static Integer getWeekBegin(String dateStr) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date;
		try {
			date = format.parse(dateStr);
			return CommonUtil.getWeekBegin(date, false);
		} catch (ParseException e) {
			logger.error("时间格式话错误", e);
			return 0;
		}

	}

	/**
	 * 获取某月第一天的零点时间
	 *
	 * @author ytche
	 * @param date
	 * @return
	 * @date 2017年6月29日 上午11:07:26
	 */
	public static Integer getMonthBegin(Date date) {
		return CommonUtil.getBeginTime(Calendar.DAY_OF_MONTH, date);
	}

	/**
	 * 根据格式化字符串获取该月份的第一天0点时间
	 *
	 * @author ytche
	 * @param dateFormat
	 *            "yyyy-MM"
	 * @return
	 * @date 2017年7月27日 下午5:08:01
	 */
	public static Integer getMonthBegin(String dateFormat) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
		try {
			Date monthDate = format.parse(dateFormat);
			return CommonUtil.getMonthBegin(monthDate);
		} catch (ParseException e) {
			logger.error("时间格式化错误", e);
			return 0;
		}
	}

	public static Integer getNextMonthBegin(String dateStr) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
		try {
			Date monthDate = new DateTime(format.parse(dateStr)).plusMonths(1).toDate();
			return CommonUtil.getMonthBegin(monthDate);
		} catch (Exception e) {
			logger.error("时间格式化错误", e);
			return 0;
		}
	};

	/**
	 * 获取当月第一天的零点时间
	 *
	 * @author ytche
	 * @return
	 * @date 2017年6月29日 上午10:24:57
	 */
	public static Integer getMonthBegin() {
		return CommonUtil.getMonthBegin(new Date());
	}

	/**
	 * 获取某年第一天的零点时间
	 *
	 * @author ytche
	 * @param date
	 * @return
	 * @date 2017年6月29日 上午11:28:05
	 */
	public static Integer getYearBegin(Date date) {
		return CommonUtil.getBeginTime(Calendar.DAY_OF_YEAR, date);
	}

	/**
	 * 获取当年第一天的零点时间
	 *
	 * @author ytche
	 * @return
	 * @date 2017年6月29日 上午11:28:31
	 */
	public static Integer getYearBegin() {
		return CommonUtil.getYearBegin(new Date());
	}

	/**
	 * 根据不同的calendarType来获取某周/某月/某年第一天0点的时间
	 *
	 * @author ytche
	 * @param calendarType
	 *            使用Calendar的提供的静态字段
	 * @param date
	 * @return
	 * @date 2017年6月29日 上午11:16:42
	 */
	private static Integer getBeginTime(int calendarType, Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(calendarType, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		return (int) (calendar.getTimeInMillis() / 1000);
	}
	
	// 判断闰年
	public static boolean isLeap(int year) {
		if (((year % 100 == 0) && year % 400 == 0) || ((year % 100 != 0) && year % 4 == 0))
			return true;
		else
			return false;
	}

	// 返回当月天数
	public static int getDays(int year, int month) {
		int days;
		int FebDay = 28;
		if (isLeap(year))
			FebDay = 29;
		switch (month) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			days = 31;
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			days = 30;
			break;
		case 2:
			days = FebDay;
			break;
		default:
			days = 0;
			break;
		}
		return days;
	}
}
